package ecom;

import ecom.api.IAdminRemote;
import ecom.api.IAnnonceChercheurRemote;
import ecom.api.IAnnonceProprietaireRemote;
import ecom.api.IOptionPayanteStatelessRemote;
import ecom.api.ITimerSessionBeanConverterStateless;

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpSession;

//import org.ow2.jonas.lib.security.auth;
import org.objectweb.jonas.security.auth.callback.*;

import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;

import ecom.entity.AdminEntity;
import ecom.entity.AnnonceChercheurEntity;
import ecom.entity.AnnonceProprietaireEntity;
import ecom.entity.OptionPayante;
import java.util.ArrayList;
import java.util.List;
import javax.naming.NamingException;
//import org.objectweb.jonas.security.auth.callback.NoInputCallbackHandler;

import java.io.*;

@ManagedBean
@SessionScoped
public class AdminLogin implements Serializable {

    private static final long serialVersionUID = 1L;
    private String pseudo;
    private String mdp;// mot de passe
    //private ChercheurEntity comptechercheuractif;
    // Reno : compte chercheur logue
    //private ProprietaireEntity compteproprietaireactif;
    // Reno : compte proprietaire logue
    List<OptionPayante> listeOptionPayante = new ArrayList<OptionPayante>();
    private AnnonceChercheurEntity annoncec = new AnnonceChercheurEntity();
    private AnnonceProprietaireEntity annoncep = new AnnonceProprietaireEntity();
    private OptionPayante optionpay = new OptionPayante();
    private boolean connecte = false;
    private boolean corp;
    private AdminEntity adminactif;
    // Reno : Type du compte connecte : Chercheur = true; Propietaire = false;
    private int page;
    private long actionid;
    // Reno : page de provenance
    private float newprice;
    private int newlifecycle;
    //TODO constructor
    public boolean isConnecte() {
        return connecte;
    }

    public void setConnecte(boolean connecte) {
        this.connecte = connecte;
    }
    LoginContext loginContext;
    private Log log = LogFactory.getLog(CompteLogin.class);

    public String getPseudo() {
        return pseudo;
    }

    public void setPseudo(String pseudo) {
        this.pseudo = pseudo;
    }

    public String getMdp() {
        return mdp;
    }

    public void setMdp(String mdp) {
        this.mdp = mdp;
    }

    public List<OptionPayante> getListeOptionPayante() {
        try {
            javax.naming.Context ic = new javax.naming.InitialContext();
            IOptionPayanteStatelessRemote optPayante = (IOptionPayanteStatelessRemote) ic.lookup("ecom.OptionPayanteStateless@Remote");
            List<OptionPayante> lop = optPayante.getListeOptionPayante();
            listeOptionPayante.clear();
            for (OptionPayante op : lop) {
                listeOptionPayante.add(op);
            }
            log.debug("après la boucle for du liste des options");

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Instance introuvable", e);
        }
        return listeOptionPayante;
    }

    public void setListeOptionPayante(List<OptionPayante> listeOptionPayante) {
        this.listeOptionPayante = listeOptionPayante;
    }

//    public List<OptionPayante> getListeOptionsPayantes() {
//        try {
//            javax.naming.Context ic = new javax.naming.InitialContext();
//            IOptionPayanteStatelessRemote optPayante = (IOptionPayanteStatelessRemote) ic.lookup("ecom.OptionPayanteStateless@Remote");
//            List<OptionPayante> lop = optPayante.getListeOptionPayante();
//            for (OptionPayante op : lop) {
//                listeOptionPayante.add(op);
//            }
//
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new RuntimeException("Instance introuvable", e);
//        }
//        return listeOptionPayante;
//    }
//    private IChercheurRemote getInstanceUtilisateurChercheur() {
//        try {
//            javax.naming.Context ic = new javax.naming.InitialContext();
//            return (IChercheurRemote) ic.lookup("ecom.stateless.ChercheurStateless@Remote");
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new RuntimeException("Instance utilisateur chercheur introuvable", e);
//        }
//    }
//
//    private IProprietaireRemote getInstanceUtilisateurProprietaire() {
//        try {
//            javax.naming.Context ic = new javax.naming.InitialContext();
//            return (IProprietaireRemote) ic.lookup("ecom.stateless.ProprietaireStateless@Remote");
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new RuntimeException("Instance utilisateur proprietaire introuvable", e);
//        }
//    }
    private IAnnonceChercheurRemote getInstanceChercheur() {
        try {
            javax.naming.Context ic = new javax.naming.InitialContext();
            return (IAnnonceChercheurRemote) ic.lookup("ecom.stateless.AnnonceChercheurStateless@Remote");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Instance chercheur introuvable", e);
        }
    }

    private IAnnonceProprietaireRemote getInstanceProprietaire() {
        try {
            javax.naming.Context ic = new javax.naming.InitialContext();
            return (IAnnonceProprietaireRemote) ic.lookup("ecom.stateless.AnnonceProprietaireStateless@Remote");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Instance proprietaire introuvable", e);
        }
    }

    //TODO
    private IAdminRemote getInstanceAdmin() {
        try {
            javax.naming.Context ic = new javax.naming.InitialContext();
            return (IAdminRemote) ic.lookup("ecom.stateless.AdminStateless@Remote");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Instance administrateur introuvable", e);
        }
    }

    private IOptionPayanteStatelessRemote getInstanceOptionPayante() {
        try {
            javax.naming.Context ic = new javax.naming.InitialContext();
            return (IOptionPayanteStatelessRemote) ic.lookup("ecom.OptionPayanteStateless@Remote");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Instance optionPayante introuvable", e);
        }
    }

    // Reno : Fin
    public String login() throws LoginException {

        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();
        HttpSession http = (HttpSession) externalContext.getSession(true);
        http.setMaxInactiveInterval(-1);//negative =>jamais effacer la session

        try {

            CallbackHandler handler = new NoInputCallbackHandler(pseudo, mdp);
            loginContext = new LoginContext("jaasclientecom",
                    handler);
            loginContext.login();
            connecte = true;

            // Reno : Recuperation du type d'utilisateur

            adminactif = getInstanceAdmin().findByPseudo(pseudo);
            if (adminactif == null) {
                corp = false;
            } else {
                corp = true;
            }
            // Reno : Fin

        } catch (LoginException e) {
            return e.getMessage();
        }

        // Reno : On renvoi vers la page demandee avant de se loguer
//		switch(this.page)
//		{
//			case 1 : if(corp) return "AnnoncesChercheurNouvelle"; else return "AnnoncesProprietaireNouvelle";
//			case 2 : if(corp) return "AnnoncesChercheurFavorites"; else return "AnnoncesProprietaireFavorites";
//			case 3 : if(corp) return "AnnoncesChercheurPerso"; else return "AnnoncesProprietairePerso";
//			case 4 : return "Panier";
//			default : return "AnnoncesRecherche";
//		}
        if (corp) {
            log.debug("admin connecte youupppi");
            return "AdminAnnonces";
        }
        log.debug("admin non connecte hmmmmm");
        return "AdminTemplate";
        // Reno : Fin

    }

    public String deleteAnnoncecAd() throws NamingException {
        try {
            getInstanceChercheur().DeleteAnnonceChercheur(actionid);
        } catch (Exception e) {
            log.error("\n           Echec de la suppression de l'annonce chercheur (id: " + annoncec.getId() + ")");
            return "ErrorPage";
        }
        log.info("\n           Annonce chercheur supprimee (id: " + actionid + ")");
        return "AdminAnnonces";
    }

    public String deleteAnnoncepAd() throws NamingException {
        try {
            getInstanceProprietaire().DeleteAnnonceProprietaire(actionid);
        } catch (Exception e) {
            log.error("\n           Echec de la suppression de l'annonce proprietaire (id: " + annoncep.getId() + ")");
            return "ErrorPage";
        }
        log.info("\n           Annonce proprietaire supprimee (id: " + actionid + ")");
        return "AdminAnnonces";
    }

    public String deleteOptionPayante() throws NamingException {
        try {
            getInstanceOptionPayante().DeleteOptionPayante(actionid);
        } catch (Exception e) {
            log.error("\n           Echec de la suppression de l'option payante (id: " + optionpay.getId() + ")");
            return "ErrorPage";
        }
        log.info("\n           Option payante supprimee (id: " + actionid + ")");
        return "";

    }

    public String logout() {

        try {
            if (loginContext != null) {
                loginContext.logout();
                connecte = false;

                FacesContext facesContext = FacesContext.getCurrentInstance();
                ExternalContext externalContext = facesContext.getExternalContext();
                externalContext.invalidateSession();

            } else {
                return "error logincontext null";
            }
        } catch (Exception e) {
            return "Error log out!";
        }
        pseudo = "";
        mdp = "";
        return "AnnoncesRecherche";
    }

    public boolean isCorp() {
        return corp;
    }

    public void setCorp(boolean corp) {
        this.corp = corp;
    }

    public AdminEntity getAdminactif() {
        return adminactif;
    }

    public void setAdminactif(AdminEntity adminactif) {
        this.adminactif = adminactif;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

//    public void ModifyPriceOP(float prix) {
//        getInstanceOptionPayante().ModifyPriceOptionPayante(actionid, prix);
//    }


    public String ModifierPrixOP() throws NamingException {

        try {
            optionpay = getInstanceOptionPayante().ModifyPriceOptionPayante(optionpay.getId(), optionpay.getPrix(),optionpay.getDescription(), optionpay.getNom(), optionpay.getDureedevie());
        } catch (Exception e) {
            log.error("\n           Echec de la modifiaction de l'option payante (id: " + optionpay.getId() + ")");
            return "ErrorPage";
        }
        log.info("\n           option payante modifiee (id: " + optionpay.getId() + ")");
        return "AdminOptionsPayantes";

    }


        public String ModifierDureeOP() throws NamingException {

        try {
            optionpay = getInstanceOptionPayante().ModifyLifeCycleOptionPayante(optionpay.getId(), optionpay.getPrix(),optionpay.getDescription(), optionpay.getNom(), optionpay.getDureedevie());
        } catch (Exception e) {
            log.error("\n           Echec de la modifiaction de l'option payante (id: " + optionpay.getId() + ")");
            return "ErrorPage";
        }
        log.info("\n           Option payante modifiee (id: " + optionpay.getId() + ")");
        return "AdminOptionsPayantes";

    }

//    public void ModifyLifeCycleOP(int duree) {
//        getInstanceOptionPayante().ModifyPriceOptionPayante(actionid, duree);
//    }

  private String resultIPs;;
  public void setResultIPs(String texte){
    System.out.println("");
  }

  public String getResultIPs(){
    return resultIPs;
  }

  public String listeIPS(){
    // systemCall("ssh user@machine.com");
    systemCall("sh call_top_IPs.sh");
    //listeIPS = resultat;
    try{//copier 
 
      DataInputStream dis = 
        new DataInputStream (
                             new FileInputStream ("result_top_IPs.txt"));
      
      byte[] datainBytes = new byte[dis.available()];
      dis.readFully(datainBytes);
      dis.close();
      
      // String content = new String(datainBytes, 0, datainBytes.length);
      resultIPs = new String(datainBytes, 0, datainBytes.length);
      
      System.out.println("Content of file result_top_IPs :");
      System.out.println(resultIPs);
      
    }catch(Exception ex){
      ex.printStackTrace();
    }

    return "resultListeIPs";
  }

  public String callTopFiles(){
    // systemCall("ssh user@machine.com");
   systemCall("sh call_top-files.sh");
    return "resultTopFiles";
  }


  public String callHours(){
    // systemCall("ssh user@machine.com");
   systemCall("sh call_hours.sh");
    return "resultHours";
  }


  public String callIPS(){
    // systemCall("ssh user@machine.com");
   systemCall("sh call_IPS.sh");
    return "resultIPS";
  }


  // gicom, requete Hadoop
  public String systemCall(String command)  {

        System.out.println("Envoyer une requete ssh pour hadoop");

    StringBuffer result = new StringBuffer("");
    //    String command = "ls -lh > /tmp/log_command";
    //    ssh  -o "StrictHostKeyChecking no" -i id_rsa-pstam-keypair ubuntu@$url_instance 'source ~/.bashrc; chmod u+x test.sh ; sh ./test.sh'
    // Run the command
    try{
    
      Process p = Runtime.getRuntime().exec(command);  

      InputStream in = p.getInputStream();
      BufferedInputStream buf = new BufferedInputStream(in);
      InputStreamReader inread = new InputStreamReader(buf);
      BufferedReader bufferedreader = new BufferedReader(inread);
  
      // Read the output
      String line;
      while ((line = bufferedreader.readLine()) != null) {
        System.out.println(line);
      }
      // Check for failure
      try {
        if (p.waitFor() != 0) {
          System.err.println("exit value = " + p.exitValue());
        }
      } catch (InterruptedException e) {
        System.err.println(e);
      } finally {
        // Close the InputStream
        bufferedreader.close();
        inread.close();
        buf.close();
        in.close();
      }

    }catch (Exception e){
      System.out.println("Eh non !");
      e.printStackTrace();
    }

   
    
    return "system_call";
  }

    public long getActionid() {
        return actionid;
    }

    public void setActionid(long actionid) {
        this.actionid = actionid;
    }

    public AnnonceChercheurEntity getAnnoncec() {
        return annoncec;
    }

    public void setAnnoncec() {
        this.annoncec = new AnnonceChercheurEntity(null, "", "", "",0, "./Photos/none.png");
    }

    public AnnonceProprietaireEntity getAnnoncep() {
        return annoncep;
    }

    public void setAnnoncep() {
        this.annoncep = new AnnonceProprietaireEntity(null, "", "","", 0, 0, 0, "./Photos/none.png");
    }

    public OptionPayante getOptionpay() {
        return optionpay;
    }

    public void setOptionpay() {
        this.optionpay = new OptionPayante(-1, "", "", 0, 0, null);
    }

    public int getNewlifecycle() {
        return newlifecycle;
    }

    public void setNewlifecycle(int newlifecycle) {
        this.newlifecycle = newlifecycle;
    }

    public float getNewprice() {
        return newprice;
    }

    public void setNewprice(float newprice) {
        this.newprice = newprice;
    }

    
    
    /*
     * 
     * @author Alexandra
     * 
     */
    
    private boolean enableUpdateDevises = true; 
    
    public boolean isEnableUpdateDevises() {
		return enableUpdateDevises;
	}

	public void setEnableUpdateDevises(boolean enableUpdateDevises) {
		this.enableUpdateDevises = enableUpdateDevises;
	}

	public String automateUpdateDevises()
    {
		
		enableUpdateDevises = false;
		log.info("automateUpdateDevises()started 1");
    	try {
    		log.info("automateUpdateDevises()started2");
            javax.naming.Context ic = new javax.naming.InitialContext();
            ITimerSessionBeanConverterStateless converter =  (ITimerSessionBeanConverterStateless) ic.lookup("ecom.stateless.TimerSessionBeanConverterStateless@Remote");
            converter.createTimer(40000);
            log.info("automateUpdateDevises() finished");
            
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Instance administrateur introuvable", e);
        }
    	
    	return "AdminAnnonces";
    	
    }
    
}
